package com.atguigu.gmall.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.atguigu.gmall.component.RequestContext;
import com.atguigu.gmall.component.RequestContextStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Jerry.Su
 * @Date 2022/2/21 10:30
 * @description dubbo filter 在服务端用于dubbo rpc调用获取traceid，并绑定到threadlocal对象；消费端绑定traceid到rpccontext
 */
@Activate(group = {Constants.CONSUMER, Constants.PROVIDER})
public class TraceIdDubboFilter implements Filter {

    public static final Logger log = LoggerFactory.getLogger(TraceIdDubboFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        if (RpcContext.getContext().isConsumerSide()) {
            RpcContext.getContext().setAttachment(RequestContextStore.TRACE_ID_KEY, RequestContext.getTraceId());
        } else {
            String traceId = invocation.getAttachment(RequestContextStore.TRACE_ID_KEY);
            log.info("provider get trace id {} from consumer", traceId);
            RequestContext.setTraceId(traceId);
        }
        try {
            return invoker.invoke(invocation);
        } finally {
            if (RpcContext.getContext().isProviderSide()) {
                RequestContext.removeTraceId();
            }
        }
    }
}
